package com.jic.point.service.impl;

import com.jic.point.mapper.ConfBdApplyMapper;
import com.jic.point.mapper.ConfBdMapper;
import com.jic.point.mapper.ConfBdMoneyLogMapper;
import com.jic.point.mapper.ReportBdMapper;
import com.jic.point.model.entity.ConfBd;
import com.jic.point.model.entity.ConfBdApply;
import com.jic.point.model.entity.ConfBdMoneyLog;
import com.jic.point.model.entity.ReportBd;
import com.jic.point.service.ReportBdService;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.jic.point.constant.consist.ResponseCode;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jic.common.base.vo.PageResult;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import com.jic.point.exception.AppRuntimeException;


import lombok.extern.slf4j.Slf4j;
/**
 * 接口实现类
 *
 * @author : admin
 * @version : v1.0.0
 * @email :
 * @since : 2020-03-09 10:12:20
 */
@Service
@Slf4j
public class ReportBdServiceImpl implements ReportBdService {

	@Resource
	private ReportBdMapper mapper;

	@Resource
	private ConfBdMapper bdMapper;

	@Resource
	private ConfBdMoneyLogMapper confBdMoneyLogMapper;


	@Resource
	private ConfBdApplyMapper confBdApplyMapper;

	/**
	 * 新增记录
	 *
	 * @param request 需要保存的入参实体类
	 * @return int 是否保存成功
	 */
	@Override
	public int save(ReportBd request) {
	 int flag = mapper.insert(request);
	 if (flag == 1) {
	   return 1;
	 }else {
	   throw new AppRuntimeException(ResponseCode.EXCEPTION, "新增失败");
	 }
	}


	/**
	 * 保存或修改记录信息
	 * @param request 需要保存的入参实体类
	 * @return int 是否保存或修改成功
	 * author admin
	 * @date 2020-3-11 20:54:09
	 */
	@Override
	public int saveOrUpdate(ReportBd request){
		log.info("保存或修改记录信息，入参 = {}", JSONObject.toJSONString(request));
		try {
			if (request == null) {
				throw new AppRuntimeException(ResponseCode.EXCEPTION,"入参为空");
			}
			if (request.getId() != null) {
				log.info("保存或修改记录信息，修改，入参 = {}", JSONObject.toJSONString(request));
				int flag = mapper.updateByPrimaryKey(request);
				if(flag == 1){
				  return 1;
				}
			}else{
				log.info("保存或修改记录信息，保存，入参 = {}", JSONObject.toJSONString(request));
				int flag = mapper.insertSelective(request);
				if(flag == 1){
				  return 1;
				}else{
				  throw new AppRuntimeException(ResponseCode.EXCEPTION,"修改失败");
				}
			}
		} catch (Exception e) {
			log.error("用户保存或修改失败", e);
			throw new AppRuntimeException(ResponseCode.EXCEPTION,"用户保存或修改失败");
		}
	     return -1;
	}

	/**
	 * 删除记录
	 *
	 * @param request 需要删除,含有主键的入参实体类
	 * @return int 是否删除成功
	 */
	@Override
	public int deleteByPrimaryKey(ReportBd request) {
		int flag = mapper.deleteByPrimaryKey(request);
	    if (flag == 1) {
	      return 1;
	    }else {
	      throw new AppRuntimeException(ResponseCode.EXCEPTION, "删除失败");
	    }
	}


	/**
	 * 逻辑删除记录
	 *
	 * @param request 含有主键的逻辑删除实体类
	 * @return int 是否逻辑删除成功
	 */
	@Override
	public int deleteByPrimaryKeyLogically(ReportBd request) {
		request.setDeleteFlag(1);
		int flag = mapper.updateByPrimaryKey(request);
	    if (flag == 1) {
	      return 1;
	    }else {
	      throw new AppRuntimeException(ResponseCode.EXCEPTION, "逻辑删除记录失败");
	    }
	}


	/**
	 * 修改
	 *
	 * @param request
	 * @return
	 */
	@Override
	public int updateByPrimaryKeySelective(ReportBd request){
		try {
			log.info("修改记录");
			ReportBd param = new ReportBd();
			BeanUtils.copyProperties(request, param);
			int flag = mapper.updateByPrimaryKeySelective(param);
	        if (flag == 1) {
	         return 1;
	        }else {
	          throw new AppRuntimeException(ResponseCode.EXCEPTION, "修改记录失败");
	        }
		} catch (Exception e) {
			log.error("修改记录失败", e);
			throw new AppRuntimeException(ResponseCode.EXCEPTION,"修改记录失败");
		}

	}

	/**
	 * 记录详情
	 *
	 * @param request 查询的入参实体类
	 * @return 数据库查询到的实体类
	 */
	@Override
	public ReportBd getByPrimaryKey(ReportBd request) {
		return mapper.selectByPrimaryKey(request);
	}


	/**
	 * 分页查询
	 *
	 * @param request 分页查询入参实体类
	 * @return 含有分页信息的实体类列表
	 */
	@Override
	public PageInfo<ReportBd> listPageBySelective(ReportBd request, int pageNum, int pageSize) {
	PageHelper.startPage(pageNum, pageSize);
	PageHelper.orderBy(" create_time desc");
	List<ReportBd> list = mapper.listPageBySelective(request);
	PageInfo pageInfo = new PageInfo(list);
	PageResult<ReportBd> result = new PageResult<>();
	result.setTotal(pageInfo.getTotal());
	result.setRows(list);
	return new PageInfo(list);
	}

	/**
	 * 不分页查询
	 *
	 * @param request 不分页查询入参实体类
	 * @return 数据库查到的实体类列表
	 */
	@Override
	public List<ReportBd> listAllRecord(ReportBd request) {
		//分页处理
		request.setDeleteFlag(0);
		return mapper.selectBySelective(request);
	}

	/**
	 * @description: 生成BD部门
	 * @return:
	 * @author: fengrui
	 * @time: 2020/12/01 14:49
	 */
	@Override
	@Scheduled(cron = "0 0 0 1 * ?") //每月1号的00:00自动执行一次
	public void generateBDRules() {
		Date date = new Date();//获取当前时间
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH,-1); //上一个月
		List<String> list = new ArrayList<>();
		list.add("add"); //新增金额
		list.add("available"); //可用金额
		list.add("total"); //总金额
		list.add("frozen"); // 冻结金额
		list.add("apply"); //这个我暂时也不知道
		list.add("consume"); //消费金额
		list.add("real_left");//剩余金额
		List<ReportBd> confBdMoneyLogList = new ArrayList<>();
		for (String value : list) {
			List<ConfBdMoneyLog> reportBdMapperList = new ArrayList<>();
			List<ConfBd> bds = new ArrayList<>();
			switch (value){
				case "add":
					reportBdMapperList.addAll(confBdMoneyLogMapper.selectAddMoney(calendar.getTime(),3));
					break;
				case "available":
					bds = bdMapper.selectBdAvailable();
					break;
				case "total":
					bds = bdMapper.selectBdTotal();
					break;
				case "frozen":
					bds = bdMapper.sekectBdFrozen();
					break;
				case "apply":
					List<ConfBdApply> confBdApplies =  confBdApplyMapper.selectByApply(calendar.getTime());
					confBdMoneyLogList.addAll(confBdApplies.stream().map(item->{
						ReportBd confBd=new  ReportBd();
						confBd.setBdCode(item.getCode());
						confBd.setBdName(item.getName());
						confBd.setReportType(value);
						confBd.setTimeType("month");
						return confBd;
					}).collect(Collectors.toList()));
					break;
				case "consume":
					reportBdMapperList.addAll(confBdMoneyLogMapper.selectAddMoney(calendar.getTime(),1));
					break;
				case "real_left":
					bds = bdMapper.sekectBdRealLeft();
					break;
			}
			if (bds.size()<1 || reportBdMapperList.size()<1){
				continue;
			}else if(value.equals("add")||value.equals("total")||value.equals("frozen")|| value.equals("real_left")){
				confBdMoneyLogList.addAll(bds.stream().map(item -> {
					ReportBd reportBd = new ReportBd();
					reportBd.setBdCode(item.getCode());
					if (value.equals("available")){
						reportBd.setMoney(item.getAvailable());
					}else if(value.equals("frozen")){
						reportBd.setMoney(item.getFrozen());
					}else if (value.equals("total")){
						reportBd.setMoney(item.getTotal());
					}else if(value.equals("real_left")){
						reportBd.setMoney(item.getFrozen().add(item.getAvailable()));
					}
					reportBd.setBdName(item.getName());
					reportBd.setReportType(value);
					reportBd.setTimeType("month");
					return reportBd;
				}).collect(Collectors.toList()));
			}else{
				confBdMoneyLogList.addAll(reportBdMapperList.stream().map(item -> {
					ReportBd reportBd = new ReportBd();
					reportBd.setBdCode(item.getBdCode());
					reportBd.setMoney(item.getAmount());
					reportBd.setBdName(item.getBdName());
					reportBd.setReportType(value);
					reportBd.setTimeType("month");
					return reportBd;
				}).collect(Collectors.toList()));
			}
		}
		Integer result = mapper.listInsert(confBdMoneyLogList);
	}







}
